package com.wanlian.service.impl;

import com.wanlian.common.ConstantCode;
import com.wanlian.dao.StorageDao;
import com.wanlian.dao.StorageItemDao;
import com.wanlian.entity.Device;
import com.wanlian.entity.Storage;
import com.wanlian.entity.StorageItem;
import com.wanlian.entity.User;
import com.wanlian.error.ErrorCode;
import com.wanlian.error.SuccessCode;
import com.wanlian.model.ResultModel;
import com.wanlian.service.StorageServices;
import com.wanlian.vo.DeviceFileVo;
import com.wanlian.vo.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class StorageServicesImpl implements StorageServices {


    @Autowired
    private StorageDao storageDao;

    @Autowired
    private StorageItemDao storageItemDao;


    /**
     * 添加云盘
     *
     * @param storage
     * @return
     */
    @Override
    public ResultModel doAdd(Storage storage) {
        Storage dbStorage = storageDao.queryByUserId(storage.getUserId(), storage.getDeviceId());
        if (dbStorage != null) {
            float nowSize = dbStorage.getMovie() + dbStorage.getPhoto() + dbStorage.getMusic() + dbStorage.getOther() + dbStorage.getShare();
            if (nowSize > storage.getTotal()) {
                return new ResultModel(false, null, ErrorCode.STORAGE_SIZE_TOO_SMALL);
            } else {
                dbStorage.setTotal(storage.getTotal());
                storageDao.update(dbStorage);
            }
        } else {
            storageDao.add(storage);
        }
        return new ResultModel(true);
    }

    /**
     * 修改云盘
     *
     * @param storage
     * @return
     */
    @Override
    public ResultModel doEdit(Storage storage) {
        Storage dbStorage = this.storageDao.queryById(storage.getId());
        if (dbStorage == null) {
            return new ResultModel(false, null, ErrorCode.STORAGE_NOT_EXISTS);
        } else {
            float nowSize = dbStorage.getMovie() + dbStorage.getPhoto() + dbStorage.getMusic() + dbStorage.getOther() + dbStorage.getShare();
            if (nowSize > storage.getTotal()) {
                return new ResultModel(false, null, ErrorCode.STORAGE_SIZE_TOO_SMALL);
            }
            storageDao.updateByMerge(storage);
            return new ResultModel(true);
        }
    }

    /**
     * 添加云盘子项
     *
     * @param item
     * @return
     */
    @Override
    public ResultModel doAddItem(StorageItem item) {
        Storage storage = this.storageDao.queryById(item.getStorageId());
        if (storage == null) {
            return new ResultModel(false, null, ErrorCode.STORAGE_NOT_EXISTS);
        } else {
            if (storage.hasEnoughSize(item.getFileSize())) {
                if (item.getFileType() == ConstantCode.STORAGE_FILE_MOVIE) {
                    float moviesize = storage.getMovie() + item.getFileSize();
                    storage.setMovie(moviesize);
                }
                if (item.getFileType() == ConstantCode.STORAGE_FILE_PHOTO) {
                    float photoSize = storage.getPhoto() + item.getFileSize();
                    storage.setPhoto(photoSize);
                }
                if (item.getFileType() == ConstantCode.STORAGE_FILE_MUSIC) {
                    float musicSize = storage.getMusic() + item.getFileSize();
                    storage.setMusic(musicSize);
                }
                float other = storage.getTotal() - storage.getMusic() - storage.getPhoto() - storage.getMovie() - storage.getShare();
                storage.setOther(other);
                this.storageItemDao.add(item);
                this.storageDao.update(storage);
                return new ResultModel(true);
            } else {
                return new ResultModel(false, null, ErrorCode.STORAGE_UPLOAD_DEF);
            }
        }

    }

    @Override
    public ResultModel doEditItem(StorageItem storage) {
        //修改时间
        // storage.setUploadTime(DateUtil.currentTimestamp());
        storageItemDao.update(storage);
        return new ResultModel();
    }

    @Override
    public ResultModel doDelete(StorageItem item) {
        StorageItem dbStorageItem = storageItemDao.queryById(item.getId());
        ResultModel resultModel = new ResultModel();
        Storage storage = storageDao.queryById(item.getStorageId());
        if (storage == null) {
            return new ResultModel(false, ErrorCode.STORAGE_NOT_EXISTS);
        } else {
            if (item.getFileType() == ConstantCode.STORAGE_FILE_MOVIE) {
                float moviesize = storage.getMovie() - item.getFileSize();
                storage.setMovie(moviesize);
            }
            if (item.getFileType() == ConstantCode.STORAGE_FILE_PHOTO) {
                float photoSize = storage.getPhoto() - item.getFileSize();
                storage.setPhoto(photoSize);
            }
            if (item.getFileType() == ConstantCode.STORAGE_FILE_MUSIC) {
                float musicSize = storage.getMusic() - item.getFileSize();
                storage.setMusic(musicSize);
            }
        }

        //修改空闲大小
        float other = storage.getTotal() - storage.getMusic() - storage.getPhoto() - storage.getMovie() - storage.getShare();
        storage.setOther(other);

        // storageItemDao.doDelete(item);

        storageItemDao.delete(item.getId());
        storageDao.update(storage);
        resultModel.setBresult(true);
        resultModel.setMessage(SuccessCode.STORAGE_DELETE);

        return resultModel;
    }


    /**
     * 查询用户云盘
     *
     * @param userId
     * @return
     */
    @Override
    public ResultModel queryStorageByUserId(int userId, String deviceId) {
        Storage storage = storageDao.queryByUserId(userId, deviceId);
        if (storage == null) {
            return new ResultModel(false);
        }
        Long movie =storageItemDao.queryTotalByStorageIdAndType(storage.getId(), 0);
        Long photo =storageItemDao.queryTotalByStorageIdAndType(storage.getId(), 1);
        Long music =storageItemDao.queryTotalByStorageIdAndType(storage.getId(), 2);

        storage.setPhoto(photo);
        storage.setMovie(movie);
        storage.setMusic(music);

        storage.setOther(storage.getTotal()-photo-movie-music);

        return new ResultModel(true, storage);
    }

    /**
     * 通过storageId获取用户云盘子项
     *
     * @param storageId
     * @param page
     * @return
     */
    @Override
    public ResultModel queryItemsByStorageId(int storageId, Page page) {
        return storageItemDao.queryByStorageId(storageId, page);
    }

    /**
     * 通过storageId和文件类型获取用户云盘子项
     *
     * @param storageId
     * @param fileType
     * @return
     */
    @Override
    public ResultModel queryItemsByStorageIdAndFileType(int storageId, int fileType) {
        return storageItemDao.queryByStorageIdAndFileType(storageId, fileType);
    }

    @Override
    public StorageItem queryStorageItemById(int id) {
        return storageItemDao.queryById(id);
    }


    @Override
    public Storage queryStorageByDId(String deviceId) {
        Storage storage = storageDao.queryByDeviceId(deviceId);
        return storage;
    }


    @Override
    public ResultModel doAdd(Device device) {
        Storage storageDb = this.queryStorageByDId(device.getDeviceId());
        if (storageDb == null) {
            Storage storage = new Storage();
            storage.setUserId(device.getUserid());
            storage.setDeviceId(device.getDeviceId());
            storage.setOther(ConstantCode.STORAGE_TOTAL);
            storage.setTotal(ConstantCode.STORAGE_TOTAL);
            this.storageDao.add(storage);
        } else {
            storageDb.setUserId(device.getUserid());
            this.storageDao.update(storageDb);
        }
        return new ResultModel(true);
    }

    @Override
    public ResultModel doUpdateStorageItems(DeviceFileVo deviceFileVo) {
        Map<String, StorageItem> needUpdateMap = new HashMap<>();
        Map<String, StorageItem> needAddMap = new HashMap<>();
        Map<String, StorageItem> needDeleteMap = new HashMap<>();
        Map<String, StorageItem> newMap = new HashMap<>();
        for (StorageItem item : deviceFileVo.getItems()) {
            if (newMap.containsKey(item.getFileName()) == false) {
                newMap.put(item.getFileName(), item);
            }
        }
        Storage storage = storageDao.queryByDeviceKey(deviceFileVo.getMd5());
        if (storage != null) {
            List<StorageItem> items = storageItemDao.queryUsersBySid(storage.getId());
            Map<String, StorageItem> dbMap = new HashMap<>();
            for (StorageItem item : items) {
                if (dbMap.containsKey(item.getFileName()) == false) {
                    dbMap.put(item.getFileName(), item);
                }
            }

            for (String item : dbMap.keySet()) {
                if (newMap.containsKey(item)) {
                    StorageItem dbItem = dbMap.get(item);
                    StorageItem newItem = newMap.get(item);
                    if (dbItem.isDiff(newItem)) {
                        dbItem.setBydst(newItem);
                        needUpdateMap.put(item, dbItem);
                    }
                } else {
                    needDeleteMap.put(item, dbMap.get(item));
                }
            }

            for (String item : newMap.keySet()) {
                if (!dbMap.containsKey(item)) {
                    needAddMap.put(item, newMap.get(item));
                }
            }

            for (String item : needAddMap.keySet()) {
                needAddMap.get(item).setStorageId(storage.getId());
                storageItemDao.add(needAddMap.get(item));
            }
            for (String item : needUpdateMap.keySet()) {
                needUpdateMap.get(item).setStorageId(storage.getId());
                storageItemDao.updateByMerge(needUpdateMap.get(item));
            }
            for (String item : needDeleteMap.keySet()) {
                needDeleteMap.get(item).setStorageId(storage.getId());
                storageItemDao.delete(needDeleteMap.get(item));
            }
        }

        return new ResultModel(true);
    }


}

